package com.linwen.javase.juc.threadPool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @ClassName _01ThreadPoolDemo
 * @Description
 * @Author lin
 * @Date 2022/4/24 下午10:44
 * @Version V1.0
 *
 * 底层都是创建ThreadPoolExecutor，里面包含线程池主要的七个参数
 * 1 int corePoolSize        核心线程池大小  池中会保留的最多线程数。
 * 2 int maximumPoolSize     最大线程数   核心线程+救急线程的最大数目。
 * 3 long keepAliveTime      缓存线程时间  救急线程的生存时间，生存时间内没有新任务，此线程资源会释放。
 * 4 TimeUnit unit           时间单位  救急线程的生存时间单位，如秒、毫秒等
 * 5 BlockingQueue workQueue    阻塞队列，当没有空闲核心线程时，新来任务会加入到此队列排队，队列满会创建救急线程执行任务。
 * 6 ThreadFactory threadFactory    线程工厂  可以定制线程对象的创建，例如设置线程名字、是否是守护线程等。
 * 7 RejectedExecutionHandler handler   拒绝策略   当所有线程都在繁忙，workQueue 也放满时，会触发拒绝策略。
 *  7.1 抛异常 java.util.concurrent.ThreadPoolExecutor.AbortPolicy。
 *  7.2 由调用者执行任务 java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy。
 *  7.3 丢弃任务 java.util.concurrent.ThreadPoolExecutor.DiscardPolicy。
 *  7.4 丢弃最早排队任务 java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy。
 *
 */
public class _01ThreadPoolDemo {
    public static void main(String[] args) {
        // 固定大小的线程池，如果固定值太大 将出现OOM异常
        ExecutorService threadPool = Executors.newFixedThreadPool(1000);
        for (int i = 0; i < 1000000; i++) {
            threadPool.execute(()->{
                System.out.println(Thread.currentThread().getName()+"  working");
            });
        }
        threadPool.shutdown();

        // 创建一个单个线程的线程池，线程池中保证线程顺序执行
        ExecutorService threadPool1 = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 1000; i++) {
            int finalI = i;
            threadPool1.execute(()->{
                System.out.println(Thread.currentThread().getName()+"  working"+ finalI);
            });
        }
        threadPool1.shutdown();

        // 一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程。
        ExecutorService threadPool2 = Executors.newCachedThreadPool();
        for (int i = 0; i < 100000; i++) {
            int finalI = i;
            threadPool2.execute(()->{
                System.out.println(Thread.currentThread().getName()+"  working"+ finalI);
            });
        }
        threadPool2.shutdown();


    }
}
